﻿$kk = {}; kk = $kk;

//配置
$kk.config = {
    loadingDelay: 800, //loading加载的延迟时间,800毫秒
    stopDrawing: false,//是否停止渲染选项
}

//原始数据
$kk.data = {
    icheck: {
        js: "http://dn-blqw.qbox.me/bootstrap.icheck.min.js",
        checkboxClass: 'icheckbox_square',
        radioClass: 'iradio_square',
        increaseArea: '20%'
    },
    "switch": {
        js: "http://dn-blqw.qbox.me/bootstrap-switch.min.js",
    }
};

$kk.error = function (message) {
    throw Error(message);
};

//触发事件
$kk.fireEvent = function (jq, event) {
    if (document.all) {
        $(jq).each(function () {
            if (this.isFireEvent) {
                return;
            }
            this.isFireEvent = true;
            this.fireEvent('on' + event);
            delete this.isFireEvent;
        });
    } else {
        var e = document.createEvent("HTMLEvents");
        e.initEvent(event, true, true);
        $(jq).each(function () {
            if (this.isFireEvent) {
                return;
            }
            this.isFireEvent = true;
            this.dispatchEvent(e);
            delete this.isFireEvent;
        });
    }
};

//获取参数
$kk.getElementArgs = function (jq, option) {
    try {
        var args = $(jq).eq(0).attr("kk-data");
        if (args) {
            args = eval("(" + args + ")");
        }
        if ($.isPlainObject(args)) {
            return args;
        }
        if (option) {
            args = args || {};
            for (var i in option) {
                if (i in args == false) {
                    agrs[i] = option[i];
                }
            }
        }
        return args || {};
    } catch (e) {
        return option || {};
    }
};

//克隆对象
$kk.clonePlainObject = function (obj) {
    return $.extend({}, obj);
};

//合并对象,数值以obj1为主
$kk.mergePlainObject = function (obj1, obj2) {
    var args = $.merge([true, {}], arguments)
    return $.extend.apply($, args);
}

//分析方法参数
$kk.parseArgs = function () {
    var args = {
        Number: [],
        String: [],
        Boolean: [],
        Array: [],
        Json: [],
        DateTime: [],
        Object: [],
        Function: [],
        JQuery: [],
        Dom: []
    };
    for (var i = 0; i < arguments.length; i++) {
        var v = arguments[i];
        if (v !== null && v !== undefined) {
            if (v.constructor === Number) {
                args.Number.push(v);
            } else if (v.constructor === String) {
                args.String.push(v);
            } else if (v.constructor === Boolean) {
                args.Boolean.push(v);
            } else if (v.constructor === Date) {
                args.DateTime.push(v);
            } else if (v.constructor === Array) {
                args.Array.push(v);
            } else if (v.constructor === Function) {
                args.Function.push(v);
            } else if (v instanceof jQuery) {
                args.JQuery.push(v);
            } else if (v instanceof HTMLElement) {
                args.Dom.push(v);
            } else if ($.isPlainObject(v)) {
                args.Json.push(v);
            }
        }
    }
    return args;
};

//动态加载文件
$kk.include = function (file) {
    var option = $kk.parseArgs.apply(window, arguments);
    var files = option.Array[0] || option.String;
    var callback;
    var length = files.length;
    var ok = 0;
    if (option.Function.length > 0) {
        callback = function () {
            ok++;
            if (ok == length) {
                option.Function[0]();
            }
        };
    }

    for (var i = 0; i < length; i++) {
        var name = $.trim(files[i]);
        var att = name.split('.');
        var ext = att[att.length - 1].toLowerCase();
        if (ext == "css") {
            $("<link />").attr({ type: "text/css", rel: "stylesheet", "href": name }).appendTo("head");
            ok++;
        } else {
            $.getScript(name, callback);
        }
    }
};

//表单项渲染
$kk.drawing = function (selector) {
    if ($kk.config.stopDrawing) {
        return;
    }
    selector = $(selector || "body");
    if (selector.length == 0) {
        return;
    }
    $kk.destroy(selector);
    var filter = function (type, func) {
        var jq = selector.filter(type).add(selector.find(type));
        if (jq.length > 0) {
            func(jq);
        }
    };
    var include = function (arg, files) {
        files.push(function () {
            arg.callee.apply(arg.callee.caller, arg);
        });
        $kk.include.apply(window, files);
    };

    //a
    filter("a:not([href]),a[href=#]", function (jqs) {
        jqs.prop("href", "javascript:void(0)");
    });
    //button
    filter("button", function (jqs) {
        jqs.addClass("btn btn-default");
    })

    //icheck
    filter(":checkbox:not([draw])", function (jqs) {
        if (jqs.iCheck === undefined) {
            include(arguments, [$kk.data.icheck.js]);
            return;
        }

        jqs.each(function () {
            var jq = $(this);
            jq.iCheck($kk.getElementArgs(jq, $kk.data.icheck));
            jq.on('ifChanged', function (event) {
                this.event_ifChanged = true;
                $kk.fireEvent(this, "change"); //触发change事件
                $kk.fireEvent(this, "click");  //触发click事件
                this.event_ifChanged = false;
            });
            jq.off("change.$kk.drawing");
            jq.on("change.$kk.drawing", function () {
                if (this.event_ifChanged)
                    return;
                setTimeout(function (a, b) {
                    a.iCheck("update")
                }, 10, $(this), this.checked ? 'check' : 'uncheck');
            });
        });
    });
    //switch
    filter(":checkbox[draw=switch]", function (jqs) {
        if (jqs.bootstrapSwitch === undefined) {
            include(arguments, [$kk.data.switch.js]);
            return;
        }
        jqs.each(function () {
            var jq = $(this);
            var options = $kk.getElementArgs(jq);
            options.onSwitchChange = function (e, data) {
                //this.event_Switch = true;
                $kk.fireEvent(this, "change"); //触发change事件
                $kk.fireEvent(this, "click");  //触发click事件
                //this.event_Switch = false;
            };
            jq.bootstrapSwitch(options);
            jq.off("change.$kk.drawing");
            jq.on("change.$kk.drawing", function () {
                //if (this.event_Switch)
                //    return;
                $(this).bootstrapSwitch('setState', this.checked);
            });
        });
    });
    //select
    filter("select", function (jqs) {
        jqs.each(function () {
            var jq = $(this);
            var dd = jq.data("link_dropdown"); //取出特定数据中的jquery对象(以下称为dd)
            if (dd) dd.remove();				//如果存在,则 dd 从页面中删除
            dd = $('<div class="btn-group">');	//创建 新的dd
            jq.data("link_dropdown", dd);		//将 dd 存入select.data("link_dropdown"),以便下次创建时删除

            //按bootstarp规则创建下拉框元素
            var btn = $('<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">');
            btn.text(jq.find(":selected").text()).append('<span class="caret">'); //显示被选中的元素的text,并加入'三角形'元素
            btn.width(jq.width());		//将宽度设置和原先的select元素相同
            dd.append(btn);				//添加到dd中
            var ul = $('<ul class="dropdown-menu">');
            dd.append(ul);

            var ops = jq.find("option");//获取select中所有的option元素
            for (var i = 0; i < ops.length; i++) {
                var a = $("<a href='javascript:void(0)'>" + $(ops[i]).text() + "</a>"); //设置可点击的a标签
                a.on("click", null, $(ops[i]), function (e) { //设置li元素的click事件,并将对应的option传入事件的e.data中(第三个参数)
                    var me = $(this);
                    me.parents("ul").prev().text(me.text()).append('<span class="caret">'); //设置btn的text值为点击的li的text
                    e.data.prop("selected", true); //将对应的option selected属性设置为true
                })
                ul.append($("<li>").append(a));
            }
            jq.hide(); 		//隐藏原有的select元素
            jq.after(dd);		//将dd插入到select元素后面
            if (!jq.data("bind_change_event")) { //判断select元素是否已经绑定了change事件
                jq.on("change", function (e) {
                    var dd = $(this).data("link_dropdown"); //获取select对应的dd
                    if (dd) { //判断dd是否已经被删除
                        var index = $(this).find(":selected").index($(this));//得到select中选中的option的索引
                        dd.find("a").eq(index).click(); //在dd中选中和option相同索引的a标签,并触发click事件
                    }
                });
                jq.data("bind_change_event", true); //将绑定change标识设置为true
            }
        })
    });
};

//销毁渲染效果
$kk.destroy = function (selector) {
    selector = $(selector || "body");
    if (selector.length == 0) {
        return;
    }

    var filter = function (type, func) {
        var jq = selector.filter(type).add(selector.find(type));
        if (jq.length > 0) {
            func(jq);
        }
    };
    //icheck
    filter(":checkbox:not([draw])", function (jq) {
        if (jq.iCheck) {
            jq.iCheck("destroy");
            jq.off("change.$kk_icheck");
        }
    });
    //switch
    filter(":checkbox[draw=switch]", function (jq) {
        if (jq.bootstrapSwitch)
            jq.bootstrapSwitch('destroy');
    });
    //select
    filter("select", function (jq) {
        jq.each(function () {
            var dd = $(this).data("link_dropdown");
            if (dd) {
                $(this).show();
                dd.remove();
            }
        });
    });


};

//弹出层
$kk.popup = function (message, delay, type) {
    var config = $kk.parseArgs(delay, type);
    config = $kk.mergePlainObject({
        message: message,
        delay: config.Number[0],
        type: config.String[0],
    }, config.Json[0]);

    var panel = $("div[alert-panel]");
    if (panel.length == 0) {
        panel = $("<div alert-panel style='position:fixed;top:0;left:0;width:100%;text-align: center;' />");
        $("body").prepend(panel);
    }
    var $div = $("<div onselectstart='return false' class='alert alert-dismissible'/>")

    $div.click(function () { $(this).slideUp(function () { $(this).remove(); }); });
    config.type = {
        warning: "warning",
        warn: "warning",
        danger: "danger",
        error: "danger",
        err: "danger",
        success: "success",
        ok: "success",
        info: "info",
    }[config.type] || "info";
    $div.addClass("alert-" + config.type);
    $div.css({ padding: "7px 10px 5px", "margin-bottom": "5px", cursor: "pointer" });
    $div.append(config.message).hide();
    panel.prepend($div);
    $div.slideDown();
    if (config.delay > 0 || (config.type == "success" && config.delay == null)) {
        setTimeout(function () { $div.slideUp(function () { $(this).remove(); }); }, config.delay || 1500);
    }
    return $div;
};

//对话框
$kk.dialog = function (message, title, config, isModal, dom) {
    if ($.isPlainObject(message)) {
        return dialog(message);
    }
    var args = $kk.parseArgs(title, config, isModal, dom);
    config = args.Json[0] || {};
    if (args.String.length > 0) {
        config.title = args.String[0];
    }
    config.content = message;
    config = $kk.mergePlainObject(config, { fixed: true, });
    var maximize = config.maximize;
    delete config.maximize;
    if (config.id && config.id == "$kk-loading" && $kk.isLoading == false) {
        return;
    }
    var dia = dialog(config);

    if (maximize) {
        $(dia.node).find("[i=header]").dblclick(function () {
            if (!dia.layout || dia.layout.state != "max") {
                dia.maximize();
            } else {
                dia.restore();
            }
        });
    }

    if (args.Boolean[0] === true) {
        return dia.showModal(args.Dom[0]);
    } else {
        return dia.show(args.Dom[0]);
    }
};

//模态对话框
$kk.alert = function (message, title) {
    return this.dialog(message, title, true, { cancel: false, quickClose: true });
};

//是否处于loading状态
$kk.isLoading = false;

//显示loading框
$kk.loading = function () {
    var id = "$kk-loading";
    if (this.isLoading) {
        return false;
    }
    $kk.isLoading = true;
    $("body").append("<div shade='shade' style='position:absolute;width:100%;height:100%;top:0;left:0;' />").css("position", "relative"); //loding前遮罩
    setTimeout(this.dialog, this.config.loadingDelay, undefined, true, { id: id, height: "40px", cancel: function () { return false; }, cancelDisplay: false });
    return true;
};

//关闭loading框
$kk.unLoading = function () {
    $("body > div[shade='shade']").remove();
    var id = "$kk-loading";
    if (this.isLoading) {
        $kk.isLoading = false;
        if ("dialog" in window) {
            var x = dialog.get(id);
            x && x.remove();
        }
        return true;
    }
    return false;
}

//打开一个url
$kk.openUrl = function (url, title, isModal, width, heigth) {
    var args = this.parseArgs(title, isModal, width, heigth);
    return this.dialog(undefined, { url: url, padding: 10, title: args.String[0] || " ", width: args.Number[0], height: args.Number[1], maximize: true }, args.Boolean[0]);
}

//对话框
$kk.confirm = function (message, title, yes, no, yesFunc, noFunc) {
    var args = this.parseArgs(yes, no, yesFunc, noFunc);
    var config = {};
    config.ok = args.Function[0];
    config.cancel = args.Function[1] || true;
    config.okValue = args.String[0] || "确定";
    config.cancelValue = args.String[1] || (config.ok ? "取消" : "关闭");
    return $kk.dialog(message, title, true, config);
};

//填充数据
$kk.fillTable = function (selector, data, setData) {
    var table = $(selector)
    if (table.length != 1 || table.is("table") == false) {
        throw Error("绑定对象太多或不是table");
    }

    var func = null;
    if (setData && setData.constructor === Function) {
        func = setData;
    }

    var template = table.data("grid-template");
    if (!template) {
        template = table.find("tr[template]");
        if (template.length == 0) {
            template = table.find("tbody tr:first");
        }
        table.data("grid-template", template.show());
        template.remove();

    } else {
        table.find("[data-row]").remove();
    }
    if (!data || data.constructor !== Array) {
        return;
    }

    var tbody = table.find("tbody");
    for (var i in data) {
        var it = data[i];
        for (var j = 0; j < template.length; j++) {
            var tr = template.eq(j).clone(true, true).attr("data-row", "");
            var html = tr.html();
            html = html.replace(/\{[^{}]+\}/g, function (a) {
                var name = a.slice(1, -1);
                if (func) {
                    var value = func(it, name);
                    if (value !== undefined) {
                        return value || "";
                    }
                }
                return it[name] || "";
            });
            tbody.append(tr.show().html(html));
        }
    }
};

//填充数据2
$kk.fillData = function (selector, data, setData) {
    var table = $(selector)
    if (table.length == 1 && table.is("table")) {
        $kk.fillTable(selector, data, setData);
        return;
    }
    var func = null;
    if (setData && setData.constructor === Function) {
        func = setData;
    }
    var template = table.data("grid-template");
    if (!template) {
        template = table.find("tr[template]");
        if (template.length == 0) {
            template = table.find("tbody tr:first");
        }
        table.data("grid-template", template);
        template.remove();

    } else {
        table.find("[data-row]").remove();
    }
    if (!data || data.constructor !== Array) {
        return;
    }


};

$(document).on("change.kk_bindCheckAll", ":checkbox", function (e) {
    var flag = $(this).attr("kk_checkflag");
    if (flag) {
        function setChecked(ckb, b) {
            if (ckb.checked !== b) {
                ckb.checked = b;
                $kk.fireEvent(ckb, "change"); //触发change事件
                $kk.fireEvent(ckb, "click");  //触发click事件
            }
        };

        var first = flag.charAt(0);
        flag = flag.substr(1);
        if (kk.data[flag]) {
            return;
        }
        kk.data[flag] = true;
        if (first == "m") {
            var checked = $(this).prop("checked");
            $(":checkbox[kk_checkflag='s" + flag + "']").each(function () {
                setChecked(this, checked);
            });
        } else {
            setChecked(
                $(":checkbox[kk_checkflag='m" + flag + "']")[0],
                $(":checkbox[kk_checkflag='s" + flag + "']").not(":checked").length == 0
                );
        }

        delete kk.data[flag];
    }
});
//绑定全选事件
$kk.bindCheckAll = function (checkbox, checkboxs) {

    checkbox = $(checkbox);
    if (checkbox.length < 1) {
        this.error("至少需要1个元素");
        return;
    }
    checkboxs = $(checkboxs).not(checkbox);
    if (checkboxs.length < 1) {
        return;
    }
    var flag = Math.random();
    checkbox.attr("kk_checkflag", "m" + flag);
    checkboxs.attr("kk_checkflag", "s" + flag);
};



//树状函数
$kk.drawingTree = function (tds) {

    var tree = $.map(tds, function (n) {
        return parseInt($(n).attr("level"));
    });

    var createNode = function (index) {
        var curr = {
            lv: tree[index],
            icons: []
        };
        tree[index] = curr;
        if (curr.lv == 0) { //顶级菜单
            return curr;
        }

        for (var i = 0; i < (curr.lv - 1) ; i++) {
            curr.icons.push(0);
        }

        if (tree.length == index + 1) { //最后一个菜单
            curr.icons.push(2);
            return curr;
        }

        var next = tree[index + 1];
        var diff = next.lv - curr.lv;

        var copyIcons = function (count) {
            count = Math.min(count, next.icons.length);
            for (var i = 0; i < count; i++) {
                curr.icons[i] = (next.icons[i] == 0) ? 0 : 1;
            }
        }

        switch (diff) {
            case 0:
                copyIcons(curr.lv - 1);
                curr.icons.push(3);
                break;
            case 1:
                copyIcons(curr.lv - 1);
                var icon = next.icons.slice(-2, -1)[0];
                switch (icon) {
                    case 0:
                        curr.icons.push(2);
                        break;
                    case 1:
                        curr.icons.push(3);
                        break;
                    case 2:
                        curr.icons.push(1);
                        break;
                    case 3:
                        curr.icons.push(3);
                        break;
                    default:
                        break;
                }
                break;
            case -1:
                copyIcons(curr.lv - 2);
                if (next.lv > 0) {
                    curr.icons.pop();
                    curr.icons.push(1);
                }
                curr.icons.push(2);
                break;
            default:
                copyIcons(curr.lv - 1);
                curr.icons.push(2);
                break;
        }
        return curr;
    }

    for (var i = tree.length - 1; i >= 0; i--) {
        var td = $(tds[i]);
        var node = createNode(i);
        if (node.lv == 0) {
            continue;
        }
        var txt = td.html();
        td.empty();
        for (var j in node.icons) {
            switch (node.icons[j]) {
                case 0:
                    td.append('<div class="line_none fl">');
                    break;
                case 1:
                    td.append('<div class="line_conn fl">');
                    break;
                case 2:
                    td.append('<div class="line_bottom fl">');
                    break;
                case 3:
                    td.append('<div class="line_center fl">');
                    break;
                default:
                    break;
            }
        }
        td.find("div:last-child").html(txt);
    }
};

//格式化json对象或json字符串
$kk.jsonFormat = function (json) {
    var obj = json;
    if (json.constructor === String) {
        obj = JSON.parse(json);
    }

    var buffer = [];

    var space = function (c) {
        for (var i = 0; i < c; i++) {
            buffer.push("&nbsp;");
        }
    }

    var append = function (o, d) {
        if ($.isArray(o)) {
            buffer.push("[<br />");
            var b = false;
            for (var i in o) {
                if (b) {
                    buffer.push(" ,<br />");
                }
                b = true;
                space((d + 1) * 2);
                append(o[i], d + 1);
            }
            buffer.push("<br />");
            space(d * 2);
            buffer.push("]");
        } else if ($.isPlainObject(o)) {
            buffer.push("{<br />");
            var b = false;
            for (var i in o) {
                if (b) {
                    buffer.push(" ,<br />");
                }
                b = true;
                space((d + 1) * 2);
                buffer.push(JSON.stringify(i));
                buffer.push(" : ");
                append(o[i], d + 1);
            }
            buffer.push("<br />");
            space(d * 2);
            buffer.push("}");
        } else {
            buffer.push(JSON.stringify(o));
        }
    }
    append(obj, 0);
    return buffer.join("");
};

$kk.api = function (url) {
    function ajax(method, route, data, success) {
        if (success === undefined && $.isFunction(data)) {
            success = data;
            data = null;
        }
        var result;
        $.ajax({
            dataType: "json",
            url: url + route,
            type: method,
            data: data,
            success: function (r) {
                result = r;
                if ("Code" in result && "Message" in result && "Data" in result) {
                    if (result.Code != 0) {
                        kk.popup(result.Message, "err");
                        return;
                    }
                    result = result.Data;
                }
                success && success(result);
            },
            async: false
        });
        return result;
    }

    this.get = function (route, data, success) {
        return ajax("GET", route, data, success);
    }
    this.post = function (route, data, success) {
        return ajax("POST", route, data, success);
    }
    this.jsonp = function (route, data, success) {
        if (success === undefined && $.isFunction(data)) {
            success = data;
            data = null;
        }
        kk.loading();
        var result = $.ajax({
            dataType: "jsonp",
            url: url + route,
            type: "GET",
            data: data,
            success: function (result) {
                kk.unLoading();
                if ("Code" in result && "Message" in result && "Data" in result) {
                    if (result.Code != 0) {
                        kk.popup(result.Message, "err");
                        return;
                    }
                    result = result.Data;
                }
                success && success(result);
            },
        });
        setTimeout(function () {
            if (result.readyState == 1) {
                kk.popup("请求超时", "err");
                $kk.unLoading();
            }
        }, 10000);

    }
};
$kk.api.add = function (name, url) {
    this[name] = new $kk.api(url);
};
(function () {
    var api = new $kk.api("");
    $kk.api.post = api.post;
    $kk.api.get = api.get;
    $kk.api.jsonp = api.jsonp;
})();

//其他功能
//格式化时间
var ___DateToString = Date.prototype.toString;
Date.prototype.toString = function (format) {
    if (format === undefined) {
        return ___DateToString.apply(this);
    }
    if (format === null) {
        format = "yyyy-MM-dd HH:mm:ss";
    }

    format = format.replace(/yyyy/g, this.getFullYear());
    format = format.replace(/yyy/g, this.getYear());
    format = format.replace(/yy/g, this.getFullYear().toString().slice(-2));

    if (format.indexOf('mi') >= 0) {
        format = format.replace(/mi/g, this.getMilliseconds().toString());
    }

    if (format.indexOf('M') >= 0) {
        var M = (this.getMonth() + 1).toString();
        format = format.replace(/MM/g, ("0" + M).slice(-2));
        format = format.replace(/M/g, M);
    }

    if (format.indexOf('ddd') >= 0) {
        var xq = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"];
        format = format.replace(/ddd/g, xq[this.getDay()]);
    }

    if (format.indexOf('d') >= 0) {
        var d = this.getDate().toString();
        format = format.replace(/dd/g, ("0" + d).slice(-2));
        format = format.replace(/d/g, d);
    }


    if (format.indexOf('h') >= 0 || format.indexOf('H') >= 0) {
        var h = this.getHours().toString();
        format = format.replace(/HH/g, ("0" + h).slice(-2));
        format = format.replace(/H/g, h);
        h = h % 12;
        format = format.replace(/hh/g, ("0" + h).slice(-2));
        format = format.replace(/h/g, h);
    }

    if (format.indexOf('m') >= 0) {
        var m = this.getMinutes().toString();
        format = format.replace(/mm/g, ("0" + m).slice(-2));
        format = format.replace(/m/g, m);
    }

    if (format.indexOf('s') >= 0) {
        var s = this.getSeconds().toString();
        format = format.replace(/ss/g, ("0" + s).slice(-2));
        format = format.replace(/s/g, m);
    }

    if (format.indexOf('f') >= 0) {
        var f = this.getMilliseconds().toString();
        format = format.replace(/fff/g, ("000" + f).slice(-3));
        format = format.replace(/ff/g, ("000" + f).slice(-3).substr(0, 2));
        format = format.replace(/f/g, ("000" + f).slice(-3).substr(0, 1));
    }
    //.getMilliseconds()

    return format;
};

//ajax全局处理
jQuery(document).ajaxStart(function () {
    $kk.loading();
});
jQuery(document).ajaxStop(function () {
    $kk.unLoading();
});
jQuery(document).ajaxError(function (event, result, ajax) {
    if (result.responseText.substr(0, 12) == "error_debug:") {
        $kk.confirm(result.responseText, "DEBUG");
    } else {
        $kk.popup("请求服务器: " + ajax.url + " 失败\n原因: " + result.state(), "err");
    }
});

$(document).on("click.$kk", "a[href!=#]", function () {
    $kk.loading(); //页面跳转时的loading效果
});
//处理页面所有a标签
$("a:not([href]),a[href=#]").prop("href", "javascript:void(0)");